//region ===== gulp 依赖 =====

var gulp = require('gulp');                                 //gulp
var del = require('del');                                   //文件清理
var sass = require('gulp-sass');                            //sass 文件编译
var concat = require('gulp-concat');                        //文件合并
var uglify = require('gulp-uglify');                        //压缩
var util = require('gulp-util');						    //gulp工具类
var plumber = require('gulp-plumber');                      //错误继续
var imageMin = require('gulp-imagemin');					//图片压缩
var rename = require('gulp-rename');          				//文件名命名
var watch = require('gulp-watch');							//监听,gulp 默认的不能监听文件增加和删除
var sourceMaps = require('gulp-sourcemaps');				//源图生成
var cleanCss = require('gulp-clean-css');					//css 压缩
var runSequence = require('run-sequence');					//顺序执行
var mergeStream = require('merge-stream');					//合并多个流，返回该留时能够保证顺序执行
var gulpIf = require('gulp-if');							//gulp 条件判断

var browserSync = require('browser-sync').create();			//browser sync
var reload = browserSync.reload;							//browser reload

//endregion

//region ===== gulp 任务统一配置 =====

/**资源定义及编译配置*/
var configs = {
	release: false, // 是否是发行版，发行版将不生成 source-map。
	html: {
		src: ['./src/main/resources/templates/**/*.html'],
		watch: ['./src/main/resources/templates/**/*.html']
	},
	style: {
		libs: {
			base: {
				src: [
					'./src/asset/vendor/font-awesome/css/font-awesome.min.css',
					'./src/asset/source/bootstrap-glyphicon/css/bootstrap-glyphicon.css',
					'./src/asset/vendor/animate.css/animate.min.css',
					'./src/asset/vendor/sweetalert/dist/sweetalert.css',
                    './src/asset/source/bootstrap/dist/css/bootstrap.css',
					'./src/asset/source/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css',
					'./src/asset/vendor/select2/dist/css/select2.min.css',
					'./src/asset/vendor/bootstrap-treeview/dist/bootstrap-treeview.min.css',
					'./src/asset/source/select2tree/select2-bootstrap.min.css'
				],
				dist: './src/main/resources/static/asset/css',
				concat: 'base.min.css'
			},
			dataTable: {
				src: [
					'./src/asset/vendor/datatables.net-bs4/css/dataTables.bootstrap4.min.css',
					'./src/asset/vendor/datatables.net-responsive-bs4/css/responsive.bootstrap4.min.css',
					'./src/asset/vendor/datatables.net-buttons-bs4/css/buttons.bootstrap4.min.css',
					'./src/asset/vendor/datatables.net-select-bs4/css/select.bootstrap4.min.css',
					'./src/asset/source/datatables.net-editor/css/editor.dataTables.modify.css',
					'./src/asset/source/datatables.net-editor/css/editor.bootstrap4.min.css'
				],
				dist: './src/main/resources/static/asset/css',
				concat: 'datatables.min.css'
			},
			backIndex: {
				src: [
					'./src/asset/vendor/metisMenu/dist/metisMenu.min.css'
				],
				concat: 'index-base.css',
				dist: './src/main/resources/static/asset/css/back'
			},
			form: {
				src: [
					'./src/asset/vendor/cropperjs/dist/cropper.min.css'
				],
				concat: 'form.min.css',
				dist: './src/main/resources/static/asset/css'
			}
		},
		apps: {
			common: {
				src: [
					'./src/asset/style/common/front.scss',
					'./src/asset/style/common/back.scss'
				],
				dist: './src/main/resources/static/asset/css/common',
				include: ['./src/asset/style/common/**/*.scss'],
				watch: ['./src/asset/style/common/**/*.scss']
			},
			page: {
				src: [
					'./src/asset/style/**/*.scss',
					'!./src/asset/style/common/**/*.scss'
				],
				dist: './src/main/resources/static/asset/css',
				include: ['./src/asset/style/**/*.scss'],
				watch: [
					'./src/asset/style/front/**/*.scss',
					'./src/asset/style/back/**/*.scss'
				]
			}
		}

	},
	script: {
		libs: {
			base: {
				src: [
					'./src/asset/vendor/jquery/dist/jquery.min.js',
					'./src/asset/vendor/tether/dist/js/tether.min.js',
					'./src/asset/vendor/popper.js/dist/umd/popper.min.js',
					'./src/asset/vendor/popper.js/dist/umd/popper-utils.min.js',
					'./src/asset/source/bootstrap/dist/js/bootstrap.min.js',
					'./src/asset/vendor/jquery-slimscroll/jquery.slimscroll.min.js',
					'./src/asset/vendor/select2/dist/js/select2.full.min.js',
					'./src/asset/vendor/select2/dist/js/i18n/zh-CN.js',
					'./src/asset/source/select2tree/select2tree.js',
					'./src/asset/vendor/remarkable-bootstrap-notify/dist/bootstrap-notify.min.js',
					'./src/asset/vendor/sweetalert/docs/assets/sweetalert/sweetalert.min.js',
					'./src/asset/vendor/bootstrap-treeview/dist/bootstrap-treeview.min.js',
					'./src/asset/source/bootstrap-datetimepicker/js/bootstrap-datetimepicker.crack.js',
					'./src/asset/source/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN.js',
					'./src/asset/vendor/jsog/lib/JSOG.js',
                    './src/asset/script/ajax-hook.js'
				],
				dist: './src/main/resources/static/asset/js',
				concat: 'base.min.js'
			},
			dataTable: {
				src: [
					'./src/asset/vendor/datatables.net/js/jquery.dataTables.min.js',
					'./src/asset/vendor/datatables.net-bs4/js/dataTables.bootstrap4.min.js',
					'./src/asset/vendor/datatables.net-responsive/js/dataTables.responsive.min.js',
					'./src/asset/vendor/datatables.net-responsive-bs4/js/responsive.bootstrap4.min.js',
					'./src/asset/vendor/datatables.net-select/js/dataTables.select.min.js',
					'./src/asset/vendor/datatables.net-buttons/js/dataTables.buttons.min.js',
					'./src/asset/vendor/datatables.net-buttons/js/buttons.colVis.min.js',
					'./src/asset/vendor/datatables.net-buttons/js/buttons.flash.min.js',
					'./src/asset/vendor/datatables.net-buttons/js/buttons.html5.min.js',
					'./src/asset/vendor/datatables.net-buttons/js/buttons.print.min.js',
					'./src/asset/vendor/datatables.net-buttons-bs4/js/buttons.bootstrap4.min.js',
					'./src/asset/source/datatables.net-editor/js/dataTables.editor.crack.js',
					'./src/asset/source/datatables.net-editor/js/editor.bootstrap4.js'
				],
				dist: './src/main/resources/static/asset/js',
				concat: 'datatables.min.js'
			},
			backIndex: {
				src: [
					'./src/asset/vendor/metisMenu/dist/metisMenu.min.js'
				],
				concat: 'index-base.js',
				dist: './src/main/resources/static/asset/js/back'
			},
			form: {
				src: [
					'./src/asset/vendor/jquery-validation/dist/jquery.validate.min.js',
					'./src/asset/vendor/cropper/dist/cropper.min.js'
				],
				concat: 'form.min.js',
				dist: './src/main/resources/static/asset/js'
			}
		},
		apps: {
			common: {
				src: ['./src/asset/script/*.js'],
				dist: './src/main/resources/static/asset/js'
			},
			page: {
				src: ['./src/asset/script/**/*.js', '!./src/asset/script/*.js'],
				dist: './src/main/resources/static/asset/js'
			}
		}
	},
	font: {
		awesome: {
			src: ['./src/asset/vendor/font-awesome/fonts/*'],
			dist: './src/main/resources/static/asset/fonts'
		},
		glyphicon: {
			src: ['./src/asset/source/bootstrap-glyphicon/fonts/*'],
			dist: './src/main/resources/static/asset/fonts'
		}
	},
	image: {
		libs: {},
		apps: {
			common: {
				src: [
					'./src/asset/image/**/*.{png,jpg,jpeg,gif,ico,svg}'
				],
				watch: [
					'./src/asset/image/**/*.{png,jpg,jpeg,gif,ico,svg}'
				],
				dist: './src/main/resources/static/asset/img'
			}
		}
	}
};

//endregion

//region ===== gulp 任务 =====

function errorHandler(err) {
	util.beep();
	util.log(err);
	this.emit('end');
}

/** html 浏览器同步 */
gulp.task('html', function () {
	return gulp.src(configs.html.src)
			.pipe(reload({stream: true}));
});

/** css 库压缩合并 */
gulp.task('css:libs', function () {
	var streams = [];
	for (var name in configs.style.libs) {
		var section = configs.style.libs[name];
		var stream = gulp.src(section.src)
				.pipe(gulpIf(!configs.release, sourceMaps.init({loadMaps: true})))
				.pipe(gulpIf(configs.release, cleanCss()))
				.pipe(concat(section.concat))
				.pipe(gulpIf(!configs.release, sourceMaps.write()))
				.pipe(gulp.dest(section.dist))
				.pipe(reload({stream: true}));

		streams.push(stream);
	}
	return mergeStream(streams);
});

/** css 编译合并压缩同步浏览器 */
gulp.task('css:apps', function () {
	var streams = [];
	for (var name in configs.style.apps) {
		var section = configs.style.apps[name];
		var stream = gulp.src(section.src)
				.pipe(plumber({errorHandler: errorHandler}))
				.pipe(gulpIf(!configs.release, sourceMaps.init({loadMaps: true})))
				.pipe(sass({includePaths: section.include}))
				.pipe(gulpIf(configs.release, cleanCss()))
				.pipe(gulpIf(!configs.release, sourceMaps.write()))
				.pipe(gulp.dest(section.dist))
				.pipe(reload({stream: true}));

		streams.push(stream);
	}
	return mergeStream(streams);
});

/** js lib 压缩同步，支持不同类型的库进行打包 */
gulp.task('js:libs', function () {
	var streams = [];
	for (var name in configs.script.libs) {
		var section = configs.script.libs[name];
		var stream = gulp.src(section.src)
				.pipe(plumber({errorHandler: errorHandler}))
				.pipe(gulpIf(configs.release, uglify()))
				.pipe(concat(section.concat))
				.pipe(gulp.dest(section.dist))
				.pipe(reload({stream: true}));

		streams.push(stream);
	}
	return mergeStream(streams);
});

/** js 压缩同步，区分项目内通用文件和每个页面对应的文件。 */
gulp.task('js:apps', function () {
	var streams = [];
	for (var name in configs.script.apps) {
		var section = configs.script.apps[name];
		var stream = gulp.src(section.src)
				.pipe(plumber({errorHandler: errorHandler}))
				.pipe(gulpIf(!configs.release, sourceMaps.init({loadMaps: true})))
				.pipe(gulpIf(configs.release, uglify()))
				.pipe(gulpIf(!configs.release, sourceMaps.write()))
				.pipe(gulp.dest(section.dist))
				.pipe(reload({stream: true}));

		streams.push(stream);
	}
	return mergeStream(streams);
});

/** 其他常用资源文件 */
gulp.task('img:apps', function () {
	var minConf = {
		optimizationLevel: 5, //类型：Number  默认：3  取值范围：0-7（优化等级）
		progressive: true, //类型：Boolean 默认：false 无损压缩jpg图片
		interlaced: true, //类型：Boolean 默认：false 隔行扫描gif进行渲染
		multipass: true //类型：Boolean 默认：false 多次优化svg直到完全优化
	};

	var streams = [];
	for (var name in configs.image.apps) {
		var section = configs.image.apps[name];
		var stream = gulp.src(section.src)
				.pipe(plumber({errorHandler: errorHandler}))
				.pipe(imageMin(minConf))
				.pipe(gulp.dest(section.dist))
				.pipe(reload({stream: true}));

		streams.push(stream);
	}
	return mergeStream(streams);
});

gulp.task('font', function () {
	var streams = [];
	for (var name in configs.font) {
		var section = configs.font[name];
		var stream = gulp.src(section.src)
				.pipe(gulp.dest(section.dist))
				.pipe(reload({stream: true}));

		streams.push(stream);
	}
	return mergeStream(streams);
});

/** 编译资源文件 */
gulp.task('compile:apps', ['css:libs', 'css:apps', 'js:libs', 'js:apps']);
gulp.task('compile:stable', ['img:apps', 'font']);

/** 清理项目 */
gulp.task('clean:apps', function () {
	return del(['./src/main/resources/static/css', './src/main/resources/static/js']);
});
gulp.task('clean:all', function () {
	return del(['./src/main/resources/static']);
});

//endregion

//region ===== gulp 服务 =====

/** 开启浏览器同步插件，支持 html/css/js 变动重新加载 */
gulp.task('serve', ['compile:apps'], function () {
	browserSync.init({
		server: {
			baseDir: './src/main/resources/', //基础目录
			directory: true, //directory listing
			index: 'templates/index.html' //index file name
		},
		notify: false, //不提示同步
		online: false, //离线应用，加快启动
		open: false, //关闭自动打开页面，避免浏览器打开太多页面。
		reloadOnRestart: true //Browser sync 重启时重新加载页面
	});

	watch(configs.html.watch, reload);
	for (var name in configs.style.apps) {
		var section = configs.style.apps[name];
		section.watch && watch(section.watch, function () {
			gulp.start(['css:apps']);
		});
	}
	for (var name in configs.script.apps) {
		var section = configs.script.apps[name];
		section.src && watch(section.src, function () {
			gulp.start(['js:apps']);
		});
	}
	for (var name in configs.image.apps) {
		var section = configs.image.apps[name];
		section.watch && watch(section.watch, function () {
			gulp.start(['img:apps']);
		});
	}
});

//endregion